using System;
using System.Windows.Forms;
using System.Drawing;
using System.Data;
using System.IO;

namespace GDFlacTools.Controls.ImageComboBox
{
	/// <summary>
	/// Two column combobox for image and text
	/// </summary>
	public class ImageComboBox : ComboBox
	{
        private readonly DataSet _mDsData;

		public ImageComboBox()
		{
		    _mDsData = new DataSet();

            var dtData = new DataTable("ImageComboBox");
            dtData.Columns.Add("Image", Type.GetType("System.Object"));
            dtData.Columns.Add("Text");

            _mDsData.Tables.Add(dtData);

            // Setup owner draw code

			DrawMode = DrawMode.OwnerDrawFixed;
            DropDownStyle = ComboBoxStyle.DropDownList;

			DrawItem += ( OnDrawItem );
			SelectedIndexChanged += ( OnSelectedIndexChanged );
			DropDown += ( OnDropDown );						
		}

        ~ImageComboBox()
        {
            RemoveAll();
        }

        /// <summary>
        /// Add Image and text item.
        /// </summary>
        public void Add(string strPath, string strText)
        {
            Image imgTemp;
            //string strKey;

            if(strPath == null)
            {
                throw new Exception("Cannot pass in null value.");
            }
            
            if (File.Exists(strPath))
            {
                //strKey = Path.GetFileName(strPath);
                imgTemp = Image.FromFile(strPath);
                //m_lstImages.Images.Add(strKey, imgTemp);

            }
            else
            {
                //strKey = "";
                strPath += " not found.";
                throw new Exception(strPath);
            }

            // add to DataSet
            DataRow drData = _mDsData.Tables[0].NewRow();
            drData[0] = imgTemp;
            drData[1] = strText;
            _mDsData.Tables[0].Rows.Add(drData);

            Items.Add( strText );
        }

        public void Add(Image objImage, string strText)
        {
            //m_lstImages.Images.Add(strKey, objImage);

            // add to DataSet
            DataRow drData = _mDsData.Tables[0].NewRow();
            drData[0] = objImage;
            drData[1] = strText;
            _mDsData.Tables[0].Rows.Add(drData);

            Items.Add(strText);
        }

        public void Add(DataRow drData)
        {
            if (drData.ItemArray.Length != _mDsData.Tables[0].Columns.Count)
                throw new Exception("Invalid number of columns passed to ADD()");

            _mDsData.Tables[0].Rows.Add(drData.ItemArray);

            Items.Add(drData[1]);
        }

        public void Add(Image objImage, object obj)
        {
            //m_lstImages.Images.Add(strKey, objImage);

            // add to DataSet
            DataRow drData = _mDsData.Tables[0].NewRow();
            drData[0] = objImage;
            drData[1] = obj;
            _mDsData.Tables[0].Rows.Add(drData);

            Items.Add(obj);
        }

        public void RemoveAt(int index)
        {
            if (_mDsData.Tables[0].Rows.Count > 0 && index >= 0)
            {
                _mDsData.Tables[0].Rows.RemoveAt(index);
                Items.RemoveAt(index);
                Refresh();
            }
        }

        public void RemoveAll()
        {
            _mDsData.Clear();
            Items.Clear();
            Refresh();
        }

        public Image SelectedImage
        {
            get
            {
                if (_mDsData.Tables[0].Rows.Count == 0 || SelectedIndex == -1)
                    return null;

                return (Image)_mDsData.Tables[0].Rows[SelectedIndex][0];
            }
        }

        public object SelectedObject
        {
            get
            {
                if (_mDsData.Tables[0].Rows.Count == 0 || SelectedIndex == -1)
                    return null;

                return _mDsData.Tables[0].Rows[SelectedIndex][1];
            }
        }

        /// <summary>
        /// Replace default property. Return selected text.
        /// </summary>
        public new string SelectedText 
        {
            get
            {
                if (_mDsData.Tables[0].Rows.Count == 0 || SelectedIndex == -1)
                    return null;

                return _mDsData.Tables[0].Rows[SelectedIndex][1].ToString();
            }
        }

        public DataTable ImageListData
        {
            set
            {
                // Make sure Valid table schema
                RemoveAll();
                _mDsData.Tables.RemoveAt(0);
                _mDsData.Tables.Add(value);
                foreach (DataRow drRow in value.Rows)
                    Items.Add(drRow[1]);
            }
            get { return _mDsData.Tables[0].Copy(); }
        }

        //private void OnDrawItem(object sender, DrawItemEventArgs e)
        //{
        //    Graphics grfx = e.Graphics;

        //    e.DrawBackground();
        //    e.DrawFocusRectangle();

        //    if (e.Index >= 0)
        //    {
        //        Rectangle rect = e.Bounds;
        //        int iWidth = rect.Width;
        //        rect.X += 5;
        //        rect.Y += 1;
        //        rect.Height -= 1;
        //        rect.Width = rect.Height;
        //        string strKey = m_dsData.Tables[0].Rows[e.Index][0].ToString();
        //        if (strKey != "")
        //            grfx.DrawImage((Image)m_dsData.Tables[0].Rows[e.Index][0], rect);
        //        rect.Offset(rect.Width + 5, 0);
        //        rect.Width = iWidth;
        //        grfx.DrawString(m_dsData.Tables[0].Rows[e.Index][1].ToString(), e.Font, Brushes.Black, rect);
        //    }
        //}

        private void OnDrawItem(object sender, DrawItemEventArgs e)
        {
            Image img = null;

            if (e.Index >= 0)
            {
                int strLocationX;
                string text = string.Empty;
                string strKey = _mDsData.Tables[0].Rows[e.Index][1].ToString();

                if(!string.IsNullOrEmpty(strKey) && strKey != "Empty")
                {
                    text = strKey;
                }

                if(!string.IsNullOrEmpty(strKey))
                {
                    img = ((Image) _mDsData.Tables[0].Rows[e.Index][0]);
                }


                if(!string.IsNullOrEmpty(strKey) && img != null)
                {
                   strLocationX = img.Width + 3;
                }
                else
                {
                    strLocationX = e.Bounds.X + 3;
                }

                if (DroppedDown)
                {
                    // If the comboBox is dropped down draw the blue rectangle 
                    e.DrawBackground();

                    if ((e.State & DrawItemState.ComboBoxEdit) == DrawItemState.ComboBoxEdit)
                    {
                        // If we are drawing the selected item draw the text 
                        e.Graphics.DrawString(text, Font, Brushes.Black, new Point(strLocationX + 1, e.Bounds.Y + 2));

                        if (img != null)
                        {
                            // If we have an image available Draw the image
                            //e.Graphics.DrawImage(img, new Point(e.Bounds.X, e.Bounds.Y - 1));
                            e.Graphics.DrawImage(img, new Point(e.Bounds.X, e.Bounds.Y + 1));
                        }
                    }
                    else
                    {
                        // If we are drawing one of the item in the drop down check if the item is being highlighted
                        if (e.State.ToString().Contains(DrawItemState.Focus.ToString()) && e.State.ToString().Contains(DrawItemState.Selected.ToString()))
                        {
                            e.Graphics.DrawString(text, Font, Brushes.White, new Point(strLocationX, e.Bounds.Y + 2));
                        }
                        else
                        {
                            e.Graphics.DrawString(text, Font, Brushes.Black, new Point(strLocationX, e.Bounds.Y + 2));
                        }

                        if (img != null)
                        {
                            e.Graphics.DrawImage(img, new Point(e.Bounds.X + 2, e.Bounds.Y + 1));
                        }
                    }
                }
                else
                {
                    if (e.State.ToString().Contains(DrawItemState.Focus.ToString()) && e.State.ToString().Contains(DrawItemState.Selected.ToString()))
                    {
                        // Draw the text in White 
                        e.DrawBackground();
                        e.Graphics.DrawString(text, Font, Brushes.White, new Point(strLocationX, e.Bounds.Y + 2)); 
                        e.DrawFocusRectangle(); 

                    }
                    else
                    {
                        e.Graphics.DrawString(text, Font, Brushes.Black, new Point(strLocationX, e.Bounds.Y + 2));
                    }

                    if (img != null)
                    {
                        e.Graphics.DrawImage(img, new Point(e.Bounds.X, e.Bounds.Y + 1));
                    }
                }
            }
        } 


		private void OnSelectedIndexChanged(object sender, EventArgs e)
		{
            
		}

		/// <summary>
		/// ToDo:
		/// </summary>
		/// <param name="sender"></param>
		/// <param name="e"></param>
		/// 
		private void OnDropDown(object sender, EventArgs e)
		{

		}

        //private void InitializeComponent()
        //{
        //    SuspendLayout();
        //    // 
        //    // ImageComboBox
        //    // 
        //    MouseHover += (ImageComboBox_MouseHover);
        //    MouseMove += (ImageComboBox_MouseMove);
        //    ResumeLayout(false);

        //}

        //private void ImageComboBox_MouseHover(object sender, EventArgs e)
        //{
            
        //}

        //private void ImageComboBox_MouseMove(object sender, MouseEventArgs e)
        //{
        //    //e.Location.ToString();
        //}	
	}
}
